#ifndef CEF_C_WRAPPER_H
#define CEF_C_WRAPPER_H

#if defined(_WIN32) || defined(_WIN64)
#define CEF_C_WRAPPER_EXPORT __declspec(dllexport)
#elif defined(__linux__) || defined(__unix__)
#define CEF_C_WRAPPER_EXPORT __attribute__((visibility("default")))
#else
#error "Unsupported platform"
#endif

#include <stdio.h>
#include <string.h>

#include "capi/cef_app_capi.h"
#include "capi/views/cef_browser_view_capi.h"
#include "http_scheme_factory.h"
#include "internal/cef_types_win.h"
#include "tools/file_utils.h"
#include "tools/log_util.h"
#include "tools/embed_manifest.h"

#include "app.h"
#include "browser_view_delegate.h"
#include "browser_viwe.h"
#include "other_process.h"
#include "page_handler.h"
#include "renderer.h"
#include "tools/command_line_utils.h"
#include "tools/hash_map.h"
#include "tools/type_conversion.h"
#include "window_delegate.h"

#include "logger.h"

#include <windows.h>

bool EnableHighDpiSupport();        // 启用高Dpi

// 版本api校验, 0 表示不兼容， 1 兼容
CEF_C_WRAPPER_EXPORT int hash_api();

// 初始设置 --------------------------------------
// 初始化 cef_main_args_t
CEF_C_WRAPPER_EXPORT void *init_main_args(int argc, char *argv[]);
// 初始化 cef_settings_t
CEF_C_WRAPPER_EXPORT cef_settings_t *init_settings_t();
// 初始化 cef_browser_settings_t
CEF_C_WRAPPER_EXPORT cef_browser_settings_t *init_browser_settings();

// cef------------------------------------------------------
// 初始化进程
CEF_C_WRAPPER_EXPORT int execute_process(void *args, cef_app_t *application, void *windows_sandbox_info);
// 初始化cef
CEF_C_WRAPPER_EXPORT int initialize_cef(void *args, struct _cef_settings_t *settings, cef_app_t *application,
                                        void *windows_sandbox_info);
// 运行消息循环
CEF_C_WRAPPER_EXPORT void run_message_loop();
// 关闭cef
CEF_C_WRAPPER_EXPORT void shutdown_cef();
// 退出消息循环
CEF_C_WRAPPER_EXPORT void quit_message_loop();

// cef_string --函数------------------------------------------------------------
CEF_C_WRAPPER_EXPORT int string_utf8_to_utf16(const char *src, size_t src_len, cef_string_utf16_t *output);
CEF_C_WRAPPER_EXPORT int string_utf16_to_utf8(const char16_t *src, size_t src_len, cef_string_utf8_t *output);
CEF_C_WRAPPER_EXPORT void string_userfree_utf8_free(cef_string_userfree_utf8_t str);
CEF_C_WRAPPER_EXPORT void string_userfree_utf16_free(cef_string_userfree_utf16_t str);

// app------------------------------------------------------
// 创建 browser app
CEF_C_WRAPPER_EXPORT browser_app *browser_app_create();

// 创建browserview delegate
CEF_C_WRAPPER_EXPORT browser_view_delegate *create_browser_view_delegate(int popup_width, int popup_height, char *popup_icon_png_path, char *popup_title,int is_popup_frameless);
CEF_C_WRAPPER_EXPORT cef_app_t *get_browser_app(browser_app *app);

// browser_view------------------------------------------------------------
CEF_C_WRAPPER_EXPORT cef_browser_view_t *browser_view_create(page_handler *page, char *url,
                                                             const struct _cef_browser_settings_t *settings,
                                                             struct _cef_dictionary_value_t *extra_info,
                                                             struct _cef_request_context_t *request_context,
                                                             browser_view_delegate *delegate);

/**
 * 注册http协议，用于加载本地html和js,css等
 */
CEF_C_WRAPPER_EXPORT int register_scheme_http(cef_scheme_handler_factory_t *factory);

// 创建http协议工厂
CEF_C_WRAPPER_EXPORT cef_scheme_handler_factory_t *create_http_scheme_factory();

// 加载url
CEF_C_WRAPPER_EXPORT void load_url(cef_browser_view_t *browser_view, char *url);

/**
 * 加载本地html,
 * 路径相对于exe文件所在目录
 * 使用前需要调用register_scheme_http注册协议
 */
CEF_C_WRAPPER_EXPORT void load_file(cef_browser_view_t *browser_view, const char *html);
// 页面窗口管理
CEF_C_WRAPPER_EXPORT page_handler *create_page_handler();

// window---------------------------------------------------------------
CEF_C_WRAPPER_EXPORT window_delegate *create_window_delegate(cef_browser_view_t *browser_view, int width, int heigth, char *icon_png_path, char *title, 
                                                int is_frameless, int is_devtools);
CEF_C_WRAPPER_EXPORT cef_window_t *window_create_top_level(struct _cef_window_delegate_t *delegate);
CEF_C_WRAPPER_EXPORT cef_window_t *create_window(window_delegate *delegate);
// 设置标题
CEF_C_WRAPPER_EXPORT void set_window_title(cef_window_t *window, const char *title);
// 设置窗口位置(在 InitializeCef 后 CreateBrowserWindow 前有效）
CEF_C_WRAPPER_EXPORT void set_window_position(cef_window_t *window, int x, int y);
// 设置窗口图标(位置相对可执行文件位置, png格式
CEF_C_WRAPPER_EXPORT void set_window_icon_png(cef_window_t *window, const char *file_path);
CEF_C_WRAPPER_EXPORT void set_window_child_view(cef_window_t *window, cef_browser_view_t *browser_view);

// command_line --------------------------------------------------------------------------
// 创建命令行结构
CEF_C_WRAPPER_EXPORT cef_command_line_t *command_line_create();
// 初始化
CEF_C_WRAPPER_EXPORT void command_line_init(cef_command_line_t *command_line, int argc, char *argv[]);
// 判断进程类型  mian 0 , redderer 1, 其他 2
CEF_C_WRAPPER_EXPORT int command_line_process_type(cef_command_line_t *command_line);

// renderer------------------------------------------------------------------------------------
CEF_C_WRAPPER_EXPORT renderer_app *renderer_app_create();
CEF_C_WRAPPER_EXPORT cef_app_t *get_renderer_app(renderer_app *app);

// other app -------------------------------------------------------------------------------
CEF_C_WRAPPER_EXPORT other_app *other_app_create();
CEF_C_WRAPPER_EXPORT cef_app_t *get_other_app(browser_app *app);

// IPC---------------------------------------------------------------------------------------------------
CEF_C_WRAPPER_EXPORT void *create_ipc_value_int(int value);
CEF_C_WRAPPER_EXPORT void *create_ipc_value_double(double value);
CEF_C_WRAPPER_EXPORT void *create_ipc_value_bool(int value);
CEF_C_WRAPPER_EXPORT void *create_ipc_value_string(char *value);
CEF_C_WRAPPER_EXPORT void* create_ipc_value_binary(char* data, int size);
CEF_C_WRAPPER_EXPORT void* create_ipc_value_list();
CEF_C_WRAPPER_EXPORT void* ipc_value_list_add_element(IPC_Value* list, IPC_Value* element);
CEF_C_WRAPPER_EXPORT int ipc_value_get_element_count(IPC_Value *value);
CEF_C_WRAPPER_EXPORT void* ipc_value_get_element(IPC_Value *value, int index);


CEF_C_WRAPPER_EXPORT int ipc_value_get_int(void *ipc_value);
CEF_C_WRAPPER_EXPORT double ipc_value_get_double(void *ipc_value);
CEF_C_WRAPPER_EXPORT char *ipc_value_get_string(void *ipc_value);
CEF_C_WRAPPER_EXPORT int ipc_value_get_bool(void *ipc_value);

CEF_C_WRAPPER_EXPORT IPC_Value_Type ipc_value_get_type(void *ipc_value);

// 发送消息给渲染进程, 调用js， request_id 0， 返回， 1， 无返回
CEF_C_WRAPPER_EXPORT void ipc_main_send(cef_browser_view_t *browser_view, const char *event_name, void *value,
                                        int request_id);

// 注册js调用消息分发器
CEF_C_WRAPPER_EXPORT void set_main_process_message_handeler(on_main_process_message_handler on_handler);

// 设置日志级别--------------------------------------------------------------------------------------------------
CEF_C_WRAPPER_EXPORT void set_log_level(LogLevel level);


// ---------------------平台相关-------------------------------------------------------------------------------
/**
 * @brief 将清单文件嵌入到可执行文件中
 * 
 * @param executablePath 目标可执行文件路径
 * @param manifestPath   清单文件路径
 * @param resourceId     资源ID (应用程序通常用1，DLL用2)
 * @return int           操作结果状态码     返回0表示成功，非0表示失败（返回错误码）。
 */
CEF_C_WRAPPER_EXPORT int EmbedManifest(const char* executablePath, 
                 const char* manifestPath, 
                 int resourceId);

#endif